home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / fpc / demos / mapmaker.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-09-22  |  9.8 KB  |  382 lines

  1. Program MapMaker;
  2.  
  3. uses Exec, graphics, Intuition, Utility;
  4.  
  5. {$I tagutils.inc}
  6.  
  7. {
  8.     Patrick Quaid.
  9.     This program just draws a blocky map from straight overhead,
  10. then repeatedly splits each block into four parts and adjusts the
  11. elevation of each of the parts until it gets down to one pixel per
  12. block.  It ends up looking something like a terrain map.  It's kind
  13. of a fractal thing, but not too much.  Some program a long time ago
  14. inspired this, but I apologize for forgetting which one.  As I
  15. recall, that program was derived from Chris Gray's sc.
  16.     Once upon a time I was thinking about writing an overblown
  17. strategic conquest game, and this was the first stab at a map
  18. maker.  The maps it produces look nifty, but have no sense of
  19. geology so they're really not too useful for a game.
  20.     When the map is finished, press the left button inside the
  21. window somewhere and the program will go away.
  22. }
  23.  
  24. {
  25.     Changed the source to 2.0+.
  26.     12 May 1998.
  27.  
  28.     Translated to FPC. This was one of the first
  29.     program I tried with fpc, just to check that
  30.     the amiga units worked.
  31.     08 Aug 1998.
  32.     nils.sjoholm@mailbox.swipnet.se
  33. }
  34.  
  35. const
  36.     MinX = 0;
  37.     MaxX = 320;
  38.     MinY = 0;
  39.     MaxY = 200;
  40.  
  41. type
  42.     MapArray = array [MinX .. MaxX - 1, MinY .. MaxY - 1] of Longint;
  43.  
  44. VAR
  45.     average,x,y,
  46.     nextx,nexty,count1,
  47.     skip,level    : Longint;
  48.     rp            : pRastPort;
  49.     vp            : Pointer;
  50.     s             : pScreen;
  51.     w             : pWindow;
  52.     m             : pMessage;
  53.     Map           : MapArray;
  54.     Quit          : Boolean;
  55.     i             : Longint;
  56.     thetags       : Array[0..12] of tTagItem;
  57.  
  58. Function FixX(x : Longint): Longint;
  59. begin
  60.     if x < 0 then
  61.     FixX := x + MaxX
  62.     else if x >= MaxX then
  63.     FixX := x mod MaxX
  64.     else
  65.     FixX := x;
  66. end;
  67.  
  68. Function FixY(y : Longint) : Longint;
  69. begin
  70.     if x < 0 then
  71.     FixY := y + MaxY
  72.     else if x >= MaxY then
  73.     FixY := y mod MaxY
  74.     else
  75.     FixY := y;
  76. end;
  77.  
  78. Procedure DrawMap;
  79. begin
  80.     if skip = 1 then begin
  81.     for x := MinX to MaxX - 1 do begin
  82.         for y := MinY to MaxY - 1 DO begin
  83.         if Map[x,y] < 100 then begin
  84.             SetAPen(rp, 0);
  85.             i := WritePixel(rp, x, y)
  86.         end else begin
  87.             average := (Map[x,y] - 100) DIV 6 + 1;
  88.             if average > 15 then
  89.             average := 15;
  90.             SetAPen(rp, average);
  91.             i := WritePixel(rp, x, y)
  92.         end
  93.         end
  94.     end
  95.    end else begin
  96.     x := MinX;
  97.     while x < MaxX do begin
  98.         y := MinY;
  99.         while y < MaxY do begin
  100.         if Map[x,y] < 100 then begin
  101.             SetAPen(rp, 0);
  102.             RectFill(rp,x,y,x + skip - 1,y + skip - 1)
  103.         end else begin
  104.             average := (Map[x,y] - 100) DIV 6 + 1;
  105.             if average > 15 then
  106.             average := 15;
  107.             SetAPen(rp,average);
  108.             RectFill(rp,x,y,x + skip - 1,y + skip - 1);
  109.         end;
  110.         y := y + skip;
  111.         end;
  112.         x := x + skip;
  113.     end;
  114.     end;
  115. end;
  116.  
  117. Function Min(x,y : Longint) : Longint;
  118. begin
  119.     if x < y then
  120.     Min := x
  121.     else
  122.     Min := y;
  123. end;
  124.  
  125. Function Max(x,y : Longint) : Longint;
  126. begin
  127.     if x > y then
  128.     Max := x
  129.     else
  130.     Max := y;
  131. end;
  132.  
  133.  
  134. Function Height(x,y : Longint) : Longint;
  135. begin
  136.     Height := Map[x,y] div 32;
  137. end;
  138.  
  139. Procedure ChangeDelta(var d : Longint);
  140. begin
  141.     case Random(100) of
  142.       51..75   : if d < 1 then
  143.              Inc(d);
  144.       76..100  : if d > -1 then
  145.              Dec(d);
  146.     end;
  147. end;
  148.  
  149. Procedure MakeRivers;
  150. var
  151.     i    : Longint;
  152.     x,y,
  153.     dx,dy  : Longint;
  154.     OK   : Boolean;
  155.     LastHeight : Longint;
  156.     count1      : Longint;
  157.     cx,cy      : Longint;
  158.     Search     : Longint;
  159.     CheckHeight : Longint;
  160. begin
  161.     SetAPen(rp, 16);
  162.  
  163.     for cx := 0 to 319 do begin
  164.     for cy := 0 to 199 do begin
  165.         if (Map[cx,cy] > 153) and (Map[cx,cy] < 162) and
  166.            (Random(100) < 3) then begin
  167.  
  168.         x := cx;
  169.         y := cy;
  170.  
  171.         dx := 0;
  172.         dy := 0;
  173.         while (dx = 0) and (dy = 0) do begin
  174.             dx := Random(2) - 1;
  175.             dy := Random(2) - 1;
  176.         end;
  177.  
  178.         OK := True;
  179.  
  180.         count1 := 0;
  181.         while OK do begin
  182.             LastHeight := Map[x,y]; { Height(x,y); }
  183.             Map[x,y] := 0;
  184.             i := WritePixel(rp, x, y);
  185.  
  186.             CheckHeight := -6;
  187.             Search := 0;
  188.             repeat
  189.                 repeat
  190.                 ChangeDelta(dx);
  191.                 ChangeDelta(dy);
  192.                 until (dx <> 0) or (dy <> 0);
  193.             Inc(Search);
  194.             if (Map[FixX(x + dx), FixY(y + dy)] > 0) and
  195.                          {  (Height(FixX(x + dx), FixY(y + dy)) < CheckHeight) then begin }
  196.                (Map[FixX(x + dx), FixY(y + dy)] < (LastHeight + CheckHeight)) then begin
  197.                 x := FixX(x + dx);
  198.                 y := FixY(y + dy);
  199.                 Search := 0;
  200.             end else if Search > 200 then begin
  201.                 if CheckHeight < 6 then begin
  202.                 Inc(CheckHeight,2);
  203.                 Search := 1;
  204.                 end else begin
  205.                 Search := 0;
  206.                 OK := False;
  207.                 end;
  208.             end;
  209.             until Search = 0;
  210.  
  211.             Inc(count1);
  212.             if count1 > 150 then
  213.             OK := False;
  214.             if Map[x,y] < 100 then
  215.             OK := False;
  216.         end;
  217.         end;
  218.     end;
  219.     end;
  220. end;
  221.  
  222. Procedure MakeMap;
  223. begin
  224.  
  225.     rp:= w^.RPort;
  226.     vp:= ViewPortAddress(w);
  227.  
  228.     SetRGB4(vp, 0, 0, 0, 12); { Ocean Blue }
  229.     SetRGB4(vp, 1, 1, 1, 0);
  230.     SetRGB4(vp, 2, 0, 3, 0);
  231.     SetRGB4(vp, 3, 0, 4, 0); { Dark Green }
  232.     SetRGB4(vp, 4, 0, 5, 0);
  233.     SetRGB4(vp, 5, 1, 6, 0);
  234.     SetRGB4(vp, 6, 2, 8, 0); { Medium Green }
  235.     SetRGB4(vp, 7, 4, 10, 0);
  236.     SetRGB4(vp, 8, 6, 10, 0);
  237.     SetRGB4(vp, 9, 9, 9, 0); { Brown }
  238.     SetRGB4(vp, 10, 8, 8, 0);
  239.     SetRGB4(vp, 11, 7, 7, 0); { Dark Brown }
  240.     SetRGB4(vp, 12, 10, 10, 0); { Dark Grey }
  241.     SetRGB4(vp, 13, 10, 10, 10);
  242.     SetRGB4(vp, 14, 12, 12, 12);
  243.     SetRGB4(vp, 15, 14, 14, 15); { White }
  244.     SetRGB4(vp, 16, 0, 0, 10);   { River blue }
  245.  
  246.     Randomize; { Seed the Random Number Generator }
  247.  
  248.     level := 7;
  249.     skip  := 16;
  250.  
  251.     y := MinY;
  252.     while y < MaxY do begin
  253.     x := MinX;
  254.     while x < MaxX do begin
  255.         Map[x,y] := Random(220);
  256.         x := x + skip;
  257.     end;
  258.     y := y + skip;
  259.     end;
  260.  
  261.     DrawMap;
  262.  
  263.     for level := 2 to 5 do begin
  264.     skip := skip DIV 2;
  265.     y := MinY;
  266.     while y < MaxY do begin
  267.         if (y MOD (2*skip)) = 0 then
  268.         nexty := skip * 2
  269.         else
  270.         nexty:=skip;
  271.         x := MinX;
  272.         while x < MaxX do begin
  273.         if (x MOD (2*skip)) = 0 then
  274.             nextx := skip * 2
  275.         else
  276.             nextx := skip;
  277.         if (nextx = skip * 2) AND (nexty = skip * 2) then begin
  278.             average := Map[x,y] * 5;
  279.             count1 := 9;
  280.         end else begin
  281.             average := 0;
  282.             count1 := 4;
  283.         end;
  284.         if (nextx = skip * 2) then begin
  285.             average := average + Map[x,FixY(y - skip)];
  286.             average := average + Map[x,FixY(y + nexty)];
  287.             count1 := count1 + 2;
  288.         end;
  289.         if (nexty = skip * 2) then begin
  290.             average := average + Map[FixX(x - skip),y];
  291.             average := average + Map[FixX(x + nextx),y];
  292.             count1 := count1 + 2;
  293.         end;
  294.         average := average + Map[FixX(x-skip),FixY(y-skip)]
  295.                    + Map[FixX(x-nextx),FixY(y+nexty)]
  296.                    + Map[FixX(x+skip),FixY(y-skip)]
  297.                    + Map[FixX(x+nextx),FixY(y+nexty)];
  298.         average := (average DIV count1) +
  299.                 (Random(4) - 2) * (9 - level);
  300.         case Average of
  301.           150..255 : Average := Average + 2;
  302.           100..149 : Inc(Average);
  303.         else
  304.             Average := Average - 3;
  305.         end;
  306.         if average < 0 then
  307.             average := 0;
  308.         if average > 220 then
  309.             average := 220;
  310.         Map[x,y] := average;
  311.  
  312.         x := x + skip;
  313.         end;
  314.         m := GetMsg(w^.UserPort);
  315.         if m <> Nil then begin
  316.         Quit := True;
  317.         Exit;
  318.         end;
  319.         y := y + skip;
  320.     end;
  321.     DrawMap;
  322.     end;
  323.     MakeRivers;
  324. end;
  325.  
  326. begin
  327.     GfxBase := OpenLibrary(GRAPHICSNAME,0);
  328.     if GfxBase <> nil then begin
  329.     thetags[0] := TagItem(SA_Left,      0);
  330.     thetags[1] := TagItem(SA_Top,       0);
  331.     thetags[2] := TagItem(SA_Width,     320);
  332.     thetags[3] := TagItem(SA_Height,    200);
  333.     thetags[4] := TagItem(SA_Depth,     5);
  334.     thetags[5] := TagItem(SA_DetailPen, 3);
  335.     thetags[6] := TagItem(SA_BlockPen,  2);
  336.     thetags[7] := TagItem(SA_Type,      CUSTOMSCREEN_f);
  337.     thetags[8].ti_Tag := TAG_END;
  338.  
  339.     s := OpenScreenTagList(NIL,@thetags);
  340.  
  341.     if s <> NIL then begin
  342.  
  343.         thetags[0]  := TagItem(WA_IDCMP,        IDCMP_MOUSEBUTTONS);
  344.         thetags[1]  := TagItem(WA_Left,         MinX);
  345.         thetags[2]  := TagItem(WA_Top,          MinY);
  346.         thetags[3]  := TagItem(WA_Width,        MaxX);
  347.         thetags[4]  := TagItem(WA_Height,       MaxY);
  348.         thetags[5]  := TagItem(WA_MinWidth,     50);
  349.         thetags[6]  := TagItem(WA_MinHeight,    20);
  350.         thetags[7]  := TagItem(WA_Borderless,   1);
  351.         thetags[8]  := TagItem(WA_BackDrop,     1);
  352.         thetags[9]  := TagItem(WA_SmartRefresh, 1);
  353.         thetags[10] := TagItem(WA_Activate,     1);
  354.         thetags[11] := TagItem(WA_CustomScreen, longint(s));
  355.         thetags[12].ti_Tag := TAG_END;
  356.  
  357.         w := OpenWindowTagList(NIL,@thetags);
  358.  
  359.         IF w <> NIL THEN begin
  360.         Quit := False;
  361.         ShowTitle(s, 0);
  362.         MakeMap;
  363.         if not Quit then
  364.             m := WaitPort(w^.UserPort);
  365.         Forbid;
  366.         repeat
  367.             m := GetMsg(w^.UserPort);
  368.         until m = nil;
  369.         CloseWindow(w);
  370.         Permit;
  371.         end else
  372.         writeln('Could not open the window.');
  373.         CloseScreen(s);
  374.     end else
  375.         writeln('Could not open the screen.');
  376.     CloseLibrary(GfxBase);
  377.     end else writeln('no graphics.library');
  378. end.
  379.  
  380.  
  381.  
  382.